import store from '@/store'

/**
 * 处理请求头数据和处理结果
 * @param { Number | String } 平台传递的API版本号
 */
class HandleParamAndResult {
  constructor (apiVersion) {
    // 域名
    this.apiPath = store.state.vuex_apiPath
    // api版本号
    this.apiVersion = apiVersion
  }

  // 添加请求头
  _addHeaders () {
    // 自定义headers
    const headers = {
      'Accept': `application/json; version=${this.apiVersion || store.state.vuex_version}`
    }

    // 动态添加token
    if (store.state.vuex_token) {
      headers.Authorization = `Bearer ${store.state.vuex_token}`
    }
    return headers
  }

  // 处理请求
  dealFetch (url, options) {
    options.headers = this._addHeaders()

    // do something before request
    return new Promise((resolve, reject) => {
      const api = this.apiPath + url

      this._request(api, options).then(res => {
        resolve(res.data)
      }).catch(err => {

        // code 的特殊提示
        // if (err.code == 'xxx') {

        // }

        if (err.status == 'error') {
          err.msg = '网络连接失败，请检查网络，并刷新重试！'
        }

        uni.showToast({
        	title: err.msg,
        	icon: 'none'
        })
        reject(err)
      })
    })
  }

  // request 发起请求
  _request (url, options){

    return new Promise((resolve, reject)=>{
      uni.request({
        url,
        header: options.headers,
        data: options.params || {},
        method: options.method.toUpperCase(),
        success (res) {
          if(res.data.code !=200){
            reject(res.data)
          } else {
            resolve(res.data)
          }
        },
        fail: function (err) {
          reject(err)
        }
      })
    })
  }
}

/**
 * 封装请求方法
 * @param { Number | String } 平台传递的版本号
 */
class RequestMethod {
  constructor (apiVersion) {
    // api版本
    this.apiVersion = apiVersion
    this.$get = this.$get.bind(this)
    this.$post = this.$post.bind(this)
    this.$put = this.$put.bind(this)
    this.$patch = this.$patch.bind(this)
    this.$delete = this.$delete.bind(this)
    this.$upload = this.$upload.bind(this)
    this._v = this._v.bind(this)
    this._method = this._method.bind(this)

  }

  /**
   * 根据请求方法传入的版本号是否有效来来出版本号
   * @param { Number | String } version 版本号
   */
  _v (version) {
    return version !== undefined ? version : this.apiVersion
  }

  /**
   * 整合请求方法
   * @param { String } url 接口路由
   * @param { Object } fetch配置 请求参数
   * @param { Number | String } version2 请求方法传递的版本号，优先级高于平台传递的版本号
   */
  _method (url, options, version2) {
    return new HandleParamAndResult(this._v(version2)).dealFetch(url, options)
  }

  /**
   * get方法
   * @param { String } url 接口路由
   * @param { Object } data 请求参数
   * @param { Number | String } version2 请求方法传递的版本号，优先级高于平台传递的版本号
   */
  $get (url, data, version2) {
    return this._method(url, {
      params: data,
      method: 'get'
    }, version2)
  }

  /**
   * post方法
   * @param { String } url 接口路由
   * @param { Object } data 请求参数
   * @param { Number | String } version2 请求方法传递的版本号，优先级高于平台传递的版本号
   */
  $post (url, data, version2) {
    return this._method(url, {
      body: data,
      method: 'post',
      type: 'json'
    }, version2)
  }

  /**
   * put方法
   * @param { String } url 接口路由
   * @param { Object } data 请求参数
   * @param { Number | String } version2 请求方法传递的版本号，优先级高于平台传递的版本号
   */
  $put (url, data, version2) {
    return this._method(url, {
      body: data,
      method: 'put',
      type: 'json'
    }, version2)
  }

  /**
   * patch方法
   * @param { String } url 接口路由
   * @param { Object } data 请求参数
   * @param { Number | String } version2 请求方法传递的版本号，优先级高于平台传递的版本号
   */
  $patch (url, data, version2) {
    return this._method(url, {
      body: data,
      method: 'patch',
      type: 'json'
    }, version2)
  }

  /**
   * delete方法
   * @param { String } url 接口路由
   * @param { Object } data 请求参数
   * @param { Number | String } version2 请求方法传递的版本号，优先级高于平台传递的版本号
   */
  $delete (url, data, version2) {
    return this._method(url, {
      params: data,
      method: 'delete'
    }, version2)
  }

  /**
   * 上传方法
   * @param { String } url 接口路由
   * @param { Object } data 请求参数
   * @param { Number | String } version2 请求方法传递的版本号，优先级高于平台传递的版本号
   */
  $upload (url, data, version2) {
    return this._method(url, {
      body: data,
      method: 'post',
      type: 'formData'
    }, version2)
  }

}

export default RequestMethod
